from math import atan2, degrees

from PySide6.QtGui import QPen
from PySide6.QtWidgets import QGraphicsPathItem, QGraphicsPolygonItem

from 程序核心代码.mvvm重构.基础定义.基础图形项.连接线 import 默认样式, 默认颜色, 默认箭头大小, 画笔宽度
from 程序核心代码.mvvm重构.基础定义.基础图形项.连接线.连接线动画效果 import 路径动画
from 程序核心代码.mvvm重构.基础定义.基础图形项.连接线.连接线箭头 import 箭头
from 程序核心代码.mvvm重构.基础定义.基础图形项.连接线.连接线路径计算 import 路径计算器


class 基础连接线(QGraphicsPathItem):
    """
    连接线类，用于表示工作流中的连接线。

    Attributes:
        起点接口 (QGraphicsItem): 连接线的起点。
        结束接口 (QGraphicsItem): 连接线的终点。
        样式 (str): 连接线的样式，默认为"曲线"。
        颜色 (QColor): 连接线的颜色，默认为绿色。
        方向箭头大小 (int): 方向箭头的大小，默认为10。
        箭头项 (QGraphicsPolygonItem): 方向箭头的图形项。
        动画效果 (路径动画): 连接线的动画效果。
    """

    # 常量定义

    def __init__(self,双向: bool = False ,父项=None):
        """
        初始化连接线对象。

        Args:
            起点接口 (QGraphicsItem): 连接线的起点。
            结束接口 (QGraphicsItem): 连接线的终点。
            样式 (str, optional): 连接线的样式，默认为"曲线"。
            颜色 (QColor, optional): 连接线的颜色，默认为绿色。
            双向 (bool, optional):连接线是否为双向   使用场景 如果传递的是引用 则连接线为双向
            方向箭头大小 (int, optional): 方向箭头的大小，默认为10。
        """
        self.父项=父项
        super().__init__(父项)  # 调用父类的初始化方法

        self.样式 = 默认样式  # 设置样式属性
        self.颜色 = 默认颜色  # 设置颜色属性
        self.方向箭头大小 = 默认箭头大小  # 设置方向箭头大小属性
        #起始接口.箭头项 = None  # 初始化箭头项属性为None
        self.画笔宽度 = 画笔宽度  # 设置画笔宽度属性
        self.setPen(QPen(self.颜色, self.画笔宽度))  # 设置画笔颜色和宽度
        self.箭头项 = 箭头(大小=self.方向箭头大小, 颜色=self.颜色)

        self.动画效果 = None  # 初始化动画效果属性为None
        self.数据流向 = 双向
        self.路径动画 = None
        #起始接口.更新位置()  # 初始化位置

    def 设置样式(self, 样式):
        """
        设置连接线的样式。

        Args:
            样式 (str): 连接线的样式。
        """
        self.样式 = 样式  # 更新样式属性
        #起始接口.更新位置()  # 更新位置

    def 设置颜色(self, 颜色):
        """
        设置连接线的颜色。

        Args:
            颜色 (QColor): 连接线的颜色。
        """
        self.颜色 = 颜色  # 更新颜色属性
        self.setPen(QPen(self.颜色, self.画笔宽度))  # 设置画笔颜色和宽度
        #起始接口.更新位置()  # 更新位置

    # def 更新位置(起始接口):
    #     """
    #     更新连接线的位置和路径，同时初始化或更新箭头的路径动画。
    #     """
    #     # 获取场景坐标
    #     起点场景位置 = 起始接口.起点图形项.scenePos()
    #     终点场景位置 = 起始接口.终点图形项.scenePos()
    #
    #     # 将场景坐标转换为它们父节点的局部坐标
    #     起点位置 = 起始接口.父项.mapFromScene(起点场景位置)
    #     终点位置 = 起始接口.父项.mapFromScene(终点场景位置)
    #     起始接口.更新连接线(起点位置, 终点位置)


    def 更新连接线(self,起点坐标,终点坐标):
        路径 = 路径计算器.计算路径(self.样式, 起点坐标, 终点坐标)
        self.setPath(路径)
        if self.scene():
            if not self.路径动画:  # 初次设置路径动画
                self.箭头项.setParentItem(self.父项)
                self.路径动画 = 路径动画(self.箭头项, self.path(), 基础速度=0.3)
            self.路径动画.路径 = self.path()
            self.路径动画.路径长度 = self.路径动画.计算路径长度()
            self.路径动画.持续时间 = self.路径动画.路径长度 / self.路径动画.基础速度
        self.update()


    def 更新箭头(self):
        """
        更新箭头的位置和方向。
        """
        路径 = self.path()
        终点位置 = 路径.pointAtPercent(1.0)
        倒数第二点位置 = 路径.pointAtPercent(0.99)

        # 计算箭头的旋转角度
        角度 = degrees(atan2(终点位置.y() - 倒数第二点位置.y(),
                            终点位置.x() - 倒数第二点位置.x()))

        self.箭头项.setPos(终点位置)
        self.箭头项.setRotation(角度)

        if not self.scene().items().count(self.箭头项):
            self.scene().addItem(self.箭头项)

    def 更改流向(self, 双向: bool):
        """
        更改连接线的流向。

        Args:
            双向 (bool): 是否为双向流向。
        """
        self.数据流向 = 双向
        self.更新箭头()  # 更新箭头以反映新的流向
